\input texinfo    @c -*- texinfo -*-
@c %**start of header
@setfilename guix.info
@settitle Guix System
@documentencoding UTF-8
@documentlanguage en
@c %**end of header

@finalout
@titlepage
@title Guix System
@author Joshua Branson
@end titlepage

@contents

@ifnottex
@node Top
@top Guix System
@end ifnottex

@menu
* One more section::
* Guix System and Libreboot::
* Another section::

@detailmenu
--- The Detailed Node Listing ---

One more section

* snteahu snthu::
* santsnhu::

Guix System and Libreboot

* Preparation::
* Installation::
* Completion::
* Conclusion::
* References::
* Acknowledgements::
* License::

Installation

* Wireless Setup::

@end detailmenu
@end menu

@node One more section
@chapter One more section

snatheu sntha u

saneh sntaeh

@menu
* snteahu snthu::
* santsnhu::
@end menu

@node snteahu snthu
@section snteahu snthu

@node santsnhu
@section santsnhu

santeo husnt husnt
sante hsnh
sntahu sntea

@node Guix System and Libreboot
@chapter Guix System and Libreboot

Guix System is an exotic distribution of GNU+Linux operating system,
with Guix as package+system manager, Linux-Libre as kernel and
Shepherd as init system.

Libreboot is a de-blobbed distribution of Coreboot firmware. By
default, Libreboot comes with GRUB bootloader as a payload.

The objective of this manual is to provide step-by-step guide for
setting up Guix System (stand-alone Guix), with Full Disk
Encryption (FDE), on devices powered by Libreboot.

Any users, for their generalized use cases, need not stumble away from
this guide to accomplish the setup. Advancers, for deviant use cases,
will have to explore outside this guide for customization; although
this guide provides information that is of paramount use.

Let us begin!

@menu
* Preparation::
* Installation::
* Completion::
* Conclusion::
* References::
* Acknowledgements::
* License::
@end menu

@node Preparation
@section Preparation

In the current GNU+Linux system, open terminal as root user.

Insert USB drive and get the device letter @code{/dev/sdX}, where “X” is the
device letter.

@example
lsblk --list
@end example

@example
NAME  MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda     8:0    0 223.6G  0 disk 
sda1    8:1    0     2M  0 part 
sda2    8:2    0   3.7G  0 part 
sda3    8:3    0 219.9G  0 part /
zram0 251:0    0   512M  0 disk [SWAP]
@end example


Unmount the device just in case if it is auto-mounted.

@example
umount /dev/sdX --verbose
@end example

Download the Guix System ISO installer package and it’s GPG signature;
where “a.b.c” is the version number and “sss” is the system
architecture.
@example
wget --verbose https://ftp.gnu.org/gnu/guix/guix-system-install-a.b.c.sss-linux.iso.xz
wget --verbose https://ftp.gnu.org/gnu/guix/guix-system-install-a.b.c.sss-linux.iso.xz.sig
@end example

Import the Guix's public key.
@example
gpg --verbose --keyserver pool.sks-keyservers.net –-receive-keys 3CE464558A84FDC69DB40CFB090B11993D9AEBB5
@end example

Verify the GPG signature of the downloaded package.
@example
gpg --verbose --verify guix-system-install-a.b.c.sss-linux.iso.xz.sig
@end example

Extract ISO image from the downloaded package.
@example
xz --verbose --decompress guix-system-install-a.b.c.sss-linux.iso.xz
@end example

Write the extracted ISO image to the drive.
@example
dd if=guix-system-install-a.b.c.sss-linux.iso of=/dev/sdX status=progress; sync
@end example

Reboot the device.
@example
reboot
@end example

@node Installation
@section Installation

On reboot, as soon as the Libreboot's graphic art appears, press "S"
or choose @code{Search for GRUB2 configuration on external media [s]}. Wait
for the Guix System from USB drive to load.

Once Guix System installer starts, choose "Install using the shell
based process".

Set your keyboard layout, where “lo” is the two-letter keyboard layout
code (lower-case).
@example
loadkeys --verbose lo
@end example

Unblock network interfaces.
@example
rfkill unblock all
@end example

Get the names of network interfaces.
@example
ifconfig -v -a
@end example

@example
enp0s25   Link encap:Ethernet  HWaddr 00:1C:25:9A:37:BA
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0  TX bytes:0
          Interrupt:16 Memory:98800000-98820000

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Bcast:0.0.0.0  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:2220 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2220 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:343511  TX bytes:343511

wlp2s0    Link encap:Ethernet  HWaddr E4:CE:8F:59:D6:BF
          inet addr:172.20.1.132  Bcast:172.20.15.255  Mask:255.255.240.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:71570 errors:0 dropped:71 overruns:0 frame:0
          TX packets:41752 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:54663323  TX bytes:5894582

@end example

Bring the desired network interface (wired or wireless) up, where “nwif” is the network interface name.
@example
ifconfig -v nwif up
@end example

For wireless connection, follow the wireless setup.

@menu
* Wireless Setup::
@end menu

@node Wireless Setup
@subsection Wireless Setup

Create a configuration file using text editor, where “fname” is any
desired name for file.
@example
nano fname.conf
@end example

Choose, type and save ONE of the following snippets, where ‘net’ is
the network name, ‘pass’ is the password or passphrase and ‘uid’ is
the user identity.

For most private networks:

@example
network=@{
  ssid="net"
  key_mgmt=WPA-PSK
  psk="pass"
@}
@end example

(or)

For most public networks:

@example
network=@{
  ssid="net"
  key_mgmt=NONE
@}
@end example

(or)

For most organizational networks:
@example
network=@{
  ssid="net"
  scan_ssid=1
  key_mgmt=WPA-EAP
  identity="uid"
  password="pass"
  eap=PEAP
  phase1="peaplabel=0"
  phase2="auth=MSCHAPV2"
@}
@end example

Connect to the configured network.
@example
wpa_supplicant -B -c fname.conf -i nwif
@end example

Assign an IP address to the network interface.
@example
dhclient -v nwif
@end example

Obtain the device letter @code{/dev/sdX} in which you would like to deploy
and install Guix System, where “X” is the device letter.
@example
lsblk --list
@end example

@example
NAME  MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda     8:0    0 223.6G  0 disk 
sda1    8:1    0     2M  0 part 
sda2    8:2    0   3.7G  0 part 
sda3    8:3    0 219.9G  0 part /
zram0 251:0    0   512M  0 disk [SWAP]
@end example


Wipe the device (Ignore if the device is new).
@example
shred --verbose --random-source=/dev/urandom /dev/sdX
@end example

Load the device-mapper module in the current kernel.
@example
modprobe --verbose dm_mod
@end example

Partition the device. Follow the prompts. Just do, GPT --> New -->
Write --> Quit; defaults will be set.
@example
cfdisk /dev/sdX
#+END_SRC>

Obtain the partition number from the device, where “Y” is the
partition number.
#+BEGIN_SRC sh :results output :exports both
lsblk --list
#+END_SRC>

Encrypt the partition. Follow the prompts.
#+BEGIN_SRC sh :results output :exports both
cryptsetup --verbose --hash whirlpool --cipher serpent-xts-plain64 --verify-passphrase --use-random --key-size 512 --iter-time 500 luksFormat /dev/sdXY
#+END_SRC>

Obtain and note down the UUID of the LUKS partition.
#+BEGIN_SRC sh :results output :exports both
cryptsetup --verbose luksUUID /dev/sdXY
#+END_SRC>

Open the encrypted partition, where "luks-uuid" is the LUKS UUID and
“partname” is any desired name for partition.  cryptsetup --verbose
#+BEGIN_SRC sh :results output :exports both
luksOpen UUID=luks-uuid partname
#+END_SRC>

Create a physical volume in the partition.
#+BEGIN_SRC sh :results output :exports both
pvcreate /dev/mapper/partname --verbose
#+END_SRC>

Create a volume group in the physical volume, where "vgname" is any desired name for volume group.
#+BEGIN_SRC sh :results output :exports both
vgcreate vgname /dev/mapper/partname --verbose
#+END_SRC>

Create logical volumes in the volume group; where "num" is the number
for space in GB, and "lvnameroot" and "lvnamehome" are any desired
names for root and home volumes respectively.
#+BEGIN_SRC sh :results output :exports both
lvcreate --extents 25%VG vgname --name lvnameroot --verbose
lvcreate --extents 100%FREE vgname --name lvnamehome --verbose
#+END_SRC>

Create filesystems on the logical-volumes, where "fsnameroot" and
"fsnamehome" are any desired names for root and home filesystems
respectively.
#+BEGIN_SRC sh :results output :exports both
mkfs.btrfs --metadata dup --label fsnameroot /dev/vgname/lvnameroot
mkfs.btrfs --metadata dup --label fsnamehome /dev/vgname/lvnamehome
#+END_SRC>

Mount the filesystems under the current system.
#+BEGIN_SRC sh :results output :exports both
mount --label fsnameroot --target /mnt --types btrfs --verbose
mkdir --verbose /mnt/home && mount --label fsnamehome --target /mnt/home --types btrfs --verbose
#+END_SRC>

Create a swap file.
#+BEGIN_SRC sh :results output :exports both
dd bs=1MiB count=1GiB if=/dev/zero of=/mnt/swapfile status=progress
mkswap --verbose /mnt/swapfile
#+END_SRC>

Make the swap file readable and writable only by root account.
#+BEGIN_SRC sh :results output :exports both
chmod --verbose 600 /mnt/swapfile
#+END_SRC>

Activate the swap file.
#+BEGIN_SRC sh :results output :exports both
swapon --verbose /mnt/swapfile
#+END_SRC>

Make the installation packages to be written on the mounted root
filesystem.
#+BEGIN_SRC sh :results output :exports both
herd start cow-store /mnt
#+END_SRC>


Create the system-wide configuration files directory.
#+BEGIN_SRC sh :results output :exports both
mkdir --verbose /mnt/etc
#+END_SRC>

Create, edit and save the system configuration file by typing the
following code snippet. WATCH-OUT for variables in the code snippet
and replace them with the relevant values.
#+BEGIN_SRC sh :results output :exports both
nano /mnt/etc/config.scm
#+END_SRC>

Snippet:
#+BEGIN_SRC scheme

(use-modules
 (gnu)
 (gnu system nss))
(use-package-modules
 certs
 gnome
 linux)
(use-service-modules
 desktop
 xorg)
(operating-system
  (kernel linux-libre-lts)
  (kernel-arguments
   (append
    (list
     "iomem=relaxed")
    %default-kernel-arguments))
  (bootloader
   (bootloader-configuration
    (bootloader
     (bootloader
      (inherit grub-bootloader)
      (installer #~(const #t))))
    (keyboard-layout keyboard-layout)))
  (keyboard-layout
   (keyboard-layout
    "xy"
    "altgr-intl"))
  (host-name "hostname")
  (mapped-devices
   (list
    (mapped-device
     (source
      (uuid "luks-uuid"))
     (target "partname")
     (type luks-device-mapping))
    (mapped-device
     (source "vgname")
     (targets
      (list
       "vgname-lvnameroot"
       "vgname-lvnamehome"))
     (type lvm-device-mapping))))
  (file-systems
   (append
    (list
     (file-system
       (type "btrfs")
       (mount-point "/")
       (device "/dev/mapper/vgname-lvnameroot")
       (flags '(no-atime))
       (options "space_cache=v2")
       (needed-for-boot? #t)
       (dependencies mapped-devices))
     (file-system
       (type "btrfs")
       (mount-point "/home")
       (device "/dev/mapper/vgname-lvnamehome")
       (flags '(no-atime))
       (options "space_cache=v2")
       (dependencies mapped-devices)))
    %base-file-systems))
  (swap-devices
   (list
    "/swapfile"))
  (users
   (append
    (list
     (user-account
      (name "username")
      (comment "Full Name")
      (group "users")
      (supplementary-groups '("audio" "cdrom" "kvm" "lp" "netdev" "tape" "video" "wheel"))))
    %base-user-accounts))
  (packages
   (append
    (list
     nss-certs)
    %base-packages))
  (timezone "Zone/SubZone")
  (locale "ab_XY.1234")
  (name-service-switch %mdns-host-lookup-nss)
  (services
   (append
    (list
     (service gnome-desktop-service-type))
    %desktop-services)))
@end example

Initialize new Guix System.
#+BEGIN@math{_SRC} sh :results output :exports both
guix system init /mnt/etc/config.scm /mnt
#+END@math{_SRC}>

Reboot the device.
#+BEGIN@math{_SRC} sh :results output :exports both
reboot
#+END@math{_SRC}>

@node Completion
@section Completion

On reboot, as soon as the Libreboot graphic art appears, press “C” to
enter the command-line.

Enter the following commands and respond to first command with the LUKS Key.
#+BEGIN@math{_SRC} sh :results output :exports both
cryptomount -u luks-uuid
set root=(lvm/vgname-lvnameroot)
#+END@math{_SRC}>

Upon Guix's GRUB menu, go with the default option.

Enter the LUKS Key again, for kernel, as prompted.

Upon login screen, login as "root" with password field empty.

Open terminal.

Set passkey for the "root" user. Follow the prompts.
#+BEGIN@math{_SRC} sh :results output :exports both
passwd root
#+END@math{_SRC}>

Set passkey for the "username" user. Follow the prompts.
#+BEGIN@math{_SRC} sh :results output :exports both
passwd username
#+END@math{_SRC}>

Install flashrom and wget.
#+BEGIN@math{_SRC} sh :results output :exports both
guix package –-install flashrom wget
#+END@math{_SRC}>

Obtain the ROM chip's model and size. Look for the output line “Found
[@dots{}] flash chip [@dots{}]”.
#+BEGIN@math{_SRC} sh :results output :exports both
flashrom --verbose --programmer internal
#+END@math{_SRC}>

Download Libreboot ROM and utilities, where "YYYYMMDD" is the release
date, @code{devmod} is the device model and "N" is the ROM chip size.
#+BEGIN@math{_SRC} sh :results output :exports both
wget --verbose @uref{https://rsync.libreboot.org/stable/YYYYMMDD/rom/grub/libreboot_rYYYYMMDD_grub_devmod_Nmb.tar.xz}
wget --verbose @uref{https://rsync.libreboot.org/stable/YYYYMMDD/libreboot_rYYYYMMDD_util.tar.xz}
#+END@math{_SRC}>

Extract the downloaded files.
#+BEGIN@math{_SRC} sh :results output :exports both
tar --extract --file=libreboot@math{_rYYYYMMDD}@math{_grub}@math{_devmod}@math{_Nmb.tar.xz} --verbose
tar --extract --file=libreboot@math{_rYYYYMMDD}@math{_util.tar.xz} --verbose
#+END@math{_SRC}>

Rename the directories of extracted files.
#+BEGIN@math{_SRC} sh :results output :exports both
mv --verbose "libreboot@math{_rYYYYMMDD}@math{_grub}@math{_devmod}@math{_Nmb.tar.xz}" "libreboot@math{_rom}"
mv --verbose "libreboot@math{_rYYYYMMDD}@math{_util}" "libreboot@math{_util}"
#+END@math{_SRC}>

Copy the ROM image to the directory of cbfstool, where "kbdlo" is the
keyboard layout and "arch" is the system architecture.
#+BEGIN@math{_SRC} sh :results output :exports both
cp libreboot@math{_rom}/devmod@math{_Nmb}@math{_kbdlo}@math{_vesafb.rom} libreboot@math{_util}/cbfstool/arch/libreboot.rom
#+END@math{_SRC}>

Change directory to the directory of cbfstool.
#+BEGIN@math{_SRC} sh :results output :exports both
cd libreboot@math{_util}/cbfstool/arch/
#+END@math{_SRC}>

Extract the GRUB configuration file from the image.
#+BEGIN@math{_SRC} sh :results output :exports both
./cbfstool libreboot.rom extract -n grub.cfg -f grub.cfg
#+END@math{_SRC}>

Edit the GRUB configuration file and insert the following code snippet
above the line @code{“menuentry 'Load Operating System [o]' --hotkey='o'
--unrestricted @{ [...] @}”}.
#+BEGIN@math{_SRC} sh :results output :exports both
nano grub.cfg
#+END@math{_SRC}>

Snippet:
@example
menuentry ‘Guix System (An advanced distribution of the GNU operating system) [g]’ --hotkey=’g’ --unrestricted
@{
cryptomount -u luks-uuid
set root=(lvm/vgname-lvnameroot)
configfile /boot/grub/grub.cfg
@}
@end example

Remove the old GRUB configuration file from the ROM image.
#+BEGIN@math{_SRC} sh :results output :exports both
./cbfstool libreboot.rom remove -n grub.cfg
#+END@math{_SRC}>

Insert the new GRUB configuration file into the ROM image.
#+BEGIN@math{_SRC} sh :results output :exports both
./cbfstool libreboot.rom add -n grub.cfg -f grub.cfg -t raw
#+END@math{_SRC}>

Move the ROM image to the directory of ich9gen.
#+BEGIN@math{_SRC} sh :results output :exports both
mv libreboot.rom ~/libreboot@math{_util}/ich9deblob/arch/libreboot.rom
#+END@math{_SRC}>

Change directory to the directory of ich9gen.
#+BEGIN@math{_SRC} sh :results output :exports both
cd ~/libreboot@math{_util}/ich9deblob/arch/
#+END@math{_SRC}>

Generate descriptor+GbE images with the MAC address, where "mac-addr"
is the MAC address of the machine.
#+BEGIN@math{_SRC} sh :results output :exports both
ich9gen --macaddress mac-addr
#+END@math{_SRC}>

Insert the descriptor+GbE image into the ROM image, where "N" is the
ROM chip size.
#+BEGIN@math{_SRC} sh :results output :exports both
dd bs=12k conv=notrunc count=1 if=ich9fdgbe@math{_Nm.bin} of=libreboot.rom status=progress
#+END@math{_SRC}>

Move the ROM image to the directory of flash.
#+BEGIN@math{_SRC} sh :results output :exports both
mv libreboot.rom ~/libreboot@math{_util}/libreboot.rom
#+END@math{_SRC}>

Change directory to the directory of flash.
#+BEGIN@math{_SRC} sh :results output :exports both
cd ~/libreboot@math{_util}
#+END@math{_SRC}>

Modify the shebang of flash script, from `#!/bin/bash` to `#!/bin/sh`.
#+BEGIN@math{_SRC} sh :results output :exports both
nano flash
#+END@math{_SRC}>

Flash the ROM with the new image.
#+BEGIN@math{_SRC} sh :results output :exports both
./flash update libreboot.rom
#+END@math{_SRC}>

(or)

#+BEGIN@math{_SRC} sh :results output :exports both
./flash forceupdate libreboot.rom
#+END@math{_SRC}>

Reboot the device.
#+BEGIN@math{_SRC} sh :results output :exports both
reboot
#+END@math{_SRC}>

@node Conclusion
@section Conclusion

Everything should be stream-lined from now. Upon Libreboot's GRUB
menu, you can either press "G" or choose "Guix System (An advanced
distribution of the GNU operating system) [g]".

During the boot process, as prompted, you have to type LUKS key twice;
once for Libreboot's GRUB and once more for Linux-Libre kernel.

Generally, you will be using Libreboot's initial/default grub.cfg,
whose Guix menu-entry invokes Guix's grub.cfg located at
@code{/boot/grub/}. For trouble-shooting, you can also use Libreboot's
@code{grubtest.cfg}, which hasn't been modified.

That is it! You have now setup Guix System with Full Disk Encryption on your device powered by Libreboot. Enjoy!

@node References
@section References

[1] Guix manual (@uref{http://guix.gnu.org/manual/en/}).

[2] Libreboot documentation (@uref{https://libreboot.org/docs/}).

@node Acknowledgements
@section Acknowledgements

[1] Thanks to Guix developer, Clement Lassieur (clement@@lassieur.org),
for helping me with the Scheme code for the bootloader configuration.

[2] Thanks to Libreboot founder and developer, Leah Rowe
(leah@@libreboot.org), for helping me with the understanding of
Libreboot’s functionalities.

@node License
@section License

This work by Raghav Gururajan is licensed under the Creative Commons
Attribution-ShareAlike 4.0 International License.

To view a copy of this license, visit
@uref{https://creativecommons.org/licenses/by-sa/4.0/}

@node Another section
@chapter Another section

Hello!

@bye